package com.xbell.app.sys.dao;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.xbell.app.sys.common.GridDataSet;
import com.xbell.app.sys.common.PageInfo;

public interface AbstractBaseDaoI {


    //private Logger logger = Logger.getLogger(this.getClass());

    public Query createNativeQuery(String sql);

    /**
     * 如果是查询数量，可以直接用这个方法
     *
     * @param sql
     * @return
     * @author 王文胜
     * @date 2023年5月25日 下午2:21:17
     */
    public int getNumberSql(String sql, Map<String, Object> params);

    /**
     * 查询总数，原理 select count(*) from 你的sql
     * @param sql
     * @param params
     * @return
     */
    public int countQuery(String sql, Map<String, Object> params);

    /**
     * 返回实体类列表
     *
     * @param <T>
     * @param sql
     * @param params
     * @return
     * @author 王文胜
     * @date 2023年5月25日 下午2:24:13
     */
    public <T> List<T> queryEntityList(String sql, Map<String, Object> params);

    /**
     * 查询结果集合，返回list->map
     *
     * @param sql
     * @param params
     * @return
     * @author 王文胜
     * @date 2023年5月25日 下午2:27:45
     */
    public List<Map<String, Object>> queryList(String sql, Map<String, Object> params);

    /**
     * 查询一个
     *
     * @param <T>
     * @param sql
     * @param params
     * @return
     * @author 王文胜
     * @date 2023年5月25日 下午2:26:02
     */
    public <T> T queryEntity(String sql, Map<String, Object> params);
    
    /**
     * 查询一个
     *
     * @param <T>
     * @param sql
     * @param params
     * @return
     * @author 王文胜
     * @date 2023年5月25日 下午2:26:02
     */
    public <T> T queryEntity(String sql,String key,Object value,Object... params);

    /**
     * 查询结果集合，返回list->map
     *
     * @param sql
     * @param params
     * @return
     * @author 王文胜
     * @date 2023年5月25日 下午2:27:45
     */
    public Map<String, Object> queryMap(String sql, Map<String, Object> params);
    /**
     * 查询结果集合，返回list->map
     *
     * @param sql
     * @param params
     * @return
     * @author 王文胜
     * @date 2023年5月25日 下午2:27:45
     */
    public Map<String, Object> queryMap(String sql,String key,Object value,Object... params);
    
    public <T> T queryUnique(String sql,String key,Object value,Object... params);
    public <T> T queryUnique(String sql,Map<String, Object> params);

    /**
     * 执行更新sql语句
     *
     * @param sql
     * @param params
     * @return 影响行数
     * @author 王文胜
     * @date 2023年6月1日 下午1:26:21
     */
    public int execUpdateSql(String sql, Map<String, Object> params);
    
    /**
	 * 执行更新sql语句
	 * @author 王文胜
	 * @date 2023年6月1日 下午1:26:21
	 * @param sql
	 * @param params
	 * @return 影响行数
	 */
	public int execUpdateSql(String sql,String key,Object value,Object... params);

    /**
     * 保存实体类
     *
     * @param <T>
     * @param t
     * @return
     * @author 王文胜
     * @date 2023年6月1日 下午1:27:31
     */
    public <T> Object saveEntity(T t);

    /**
     * 修改
     *
     * @param t
     * @param <T>
     * @return
     */
    <T> void updateEntity(T t);

    /**
     * 删除多个实体类
     * @author 王文胜
     * @date 2023年6月1日 下午1:37:49
     * @param <T>
     * @param t
     * @param ids
     * @return
     */
    //public <T> Object delEntitys(T t,String[] ids);

    /**
     * 删除单个实体类
     *
     * @param <T>
     * @param t
     * @param id
     * @return
     * @author 王文胜
     * @date 2023年6月1日 下午1:38:00
     */
    public <T> void delEntity(T t);

    public void clear();

    public void flush();
    
    public void detach(Object entity);

    public void clearBySession();

    public void flushBySession();
    
    public EntityManager getEntityManager();

    /**
	 * 快速生成表格数据
	 * @author 王文胜
	 * @date 2023年6月1日 下午1:34:32
	 * @param sql
	 * @param page 从1开始，rows参数传递Integer.MAX_VALUE表示不限制
	 * @param params
	 * @return
	 */
    public GridDataSet fastPageSql(String sql, PageInfo page, Map<String,Object> params);

    /**
	 * 快速生成表格数据,并将key转为小写
	 * @author 王文胜
	 * @date 2023年6月1日 下午1:34:32
	 * @param sql
	 * @param page 从1开始，rows参数传递Integer.MAX_VALUE表示不限制
	 * @param params 参数
	 * @return
	 */
    public GridDataSet fastPageSqlWithLowercase(String sql,PageInfo page,Map<String,Object> params);

    /**
	 * 快速生成表格数据
	 * @author 王文胜
	 * @date 2023年6月1日 下午1:34:32
	 * @param sql
	 * @param page 从1开始，rows参数传递Integer.MAX_VALUE表示不限制
	 * @param params 参数
	 * @return
	 */
    public GridDataSet fastPageSql(String sql,PageInfo page,String key,Object value,Object ...args);

    /**
	 * 快速生成表格数据,并将key转为小写
	 * @author 王文胜
	 * @date 2023年6月1日 下午1:34:32
	 * @param sql
	 * @param page 从1开始，rows参数传递Integer.MAX_VALUE表示不限制
	 * @param params
	 * @return
	 */
    public GridDataSet fastPageSqlWithLowercase(String sql, PageInfo page, String key, Object value, Object ...args);

    /**
     * 将查询结果映射为map,例如查询为[{a:1,b:2},{a:2,b:3}],mapkey设置为a,valuekey设置为b,则返回结果为 {1:2,2:3}。若valuekey为空，则返回结果为{1:{a:1,b:2},2:{a:2,b:3}}
     * @author 王文胜
     * @date 2023年7月11日 上午9:38:12
     * @param <T>
     * @param sql
     * @param mapKey 结果中的key
     * @param mapValue 结果中valuekey,可为空
     * @param params 查询参数
     * @return
     */
    public <T> Map<String,T> queryMapToMap(String sql,String mapKey,String mapValue,Map<String,Object> params);
    /**
     * 查询结果映射为map,例如查询为[{a:1,b:2},{a:2,b:3}],mapkey设置为a,valuekey设置为b,则返回结果为 {1:2,2:3}。若valuekey为空，则返回结果为{1:{a:1,b:2},2:{a:2,b:3}}
     * @author 王文胜
     * @date 2023年7月11日 上午9:38:12
     * @param <T>
     * @param sql
     * @param mapKey 结果中的key
     * @param mapValue 结果中valuekey,可为空
     * @param params 查询参数
     * @return
     */
    public <T> Map<String,T> queryMapToMap(String sql,String mapKey,String mapValue,String key,Object value,Object... params);
    /**
     * * 查询hsql结果映射为map,例如查询为[{a:1,b:2},{a:2,b:3}],mapkey设置为a,valuekey设置为b,则返回结果为 {1:2,2:3}。若valuekey为空，则返回结果为{1:{a:1,b:2},2:{a:2,b:3}}
     * @author 王文胜
     * @date 2023年7月11日 上午9:42:22
     * @param <T>
     * @param sql
     * @param keyField 实体类的属性key
     * @param valueField 实体类的属性value
     * @param params
     * @return
     */
    public <T,V> Map<String,T> queryEntityToMap(String sql,String keyField,String valueField,Map<String,Object> params);
    /**
     * * 查询hsql结果映射为map,例如查询为[{a:1,b:2},{a:2,b:3],mapkey设置为a,valuekey设置为b,则返回结果为 {1:2,2:3}。若valuekey为空，则返回结果为{1:{a:1,b:2},2:{a:2,b:3}}
     * @author 王文胜
     * @date 2023年7月11日 上午9:42:22
     * @param <T>
     * @param sql
     * @param keyField 实体类的属性key
     * @param valueField 实体类的属性value
     * @param params
     * @return
     */
    public <T,V> Map<String,T> queryEntityToMap(String sql,String keyField,String valueField,String key,Object value,Object... params);
    
    /**
	 * 将数据库数字字段转为BigDecimal
	 * @param obj
	 * @return
	 * @datetime 2023年8月1日 下午1:15:17
	 * @author 王文胜
	 */
	public BigDecimal transBigDecimal(Object obj);
	
	/**
	 * 将clob字段转为string
	 * @param obj
	 * @return
	 * @datetime 2023年8月1日 下午1:16:10
	 * @author 王文胜
	 */
	public String transClobToString(Object obj);
	
	/**
	 * 获取实体类
	 * @param <T>
	 * @param cls 实体类
	 * @param pk 主键
	 * @return
	 */
	public <T> Optional<T> find(Class<T> cls,Object pk);
}
